package com.zeyuan.rpcclient.netty.helloworld01;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;

//同一个客户端对应同一个eventloop
public class HelloServer {
    public static void main(String[] args) {
        //创建一个独立的eventloopgroup,专门执行执行时间较长的事件
        EventLoopGroup group = new DefaultEventLoopGroup();


        new ServerBootstrap() //启动器，组装netty组件，启动服务器
                //有一个线程和选择器不断循环查询是否有事件，是否有accept连接
//                .group(new NioEventLoopGroup()) //booteventloop,workereventloop(selector,thread),group组
                //这里想对处理accept和read事件的eventloop进行分离
                //boss只负责ServerSocketChannel上accept事件 worker只负责socketChannel上的读写  一个是负责连接accept，一个是负责读写channel
                .group(new NioEventLoopGroup(),new NioEventLoopGroup())
                .channel(NioServerSocketChannel.class) //选择服务器的serversocketchannel实现，这里是bio
                .childHandler(
                        //添加初始化器，在连接建立后会执行
                        //channel代表和客户端进行数据读写的通道initializer初始化，负责添加新的handler
                        new ChannelInitializer<NioSocketChannel>() {

                            @Override
                            protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
                                nioSocketChannel.pipeline().addLast(new StringDecoder()); //将bytebuf转换为字符串（解码器）
                                nioSocketChannel.pipeline().addLast("handler1",new ChannelInboundHandlerAdapter(){ //自定义handler
                                    @Override //关注读事件，msg是channel发送过来的bytebuf经过stringdecoder转换成的字符串
                                    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                                        super.channelRead(ctx, msg);
                                        //如果上面不指定stringdeoder解码器,直接强转
//                                        ByteBuf bf= (ByteBuf) msg;
                                        System.out.println(msg);
                                        ctx.fireChannelRead(msg); //将消息传给下一个handler
                                    }
                                }).addLast(group,"handler2",new ChannelInboundHandlerAdapter(){
                                    //group对应handler2专门用于处理耗时较长的事件，除了boss和worker细分外，还可以细分新的group用于处理handler2中的代码，也就是说，handler可以指定group来分配线程执行里面的任务
                                    //每个channel进来都要依次执行handler，handler代码分配给指定group执行
                                    @Override
                                    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                                        super.channelRead(ctx, msg);
                                    }
                                });
                            }
                        }
                ).bind(8080);
    }
}
